//
// Created by Administrator on 2025/8/14.
//

#include "myhttp.h"
#include "printf_rtos.h"
#include "lwip/netdb.h"
#include "lwip/sockets.h"
#include "FreeRTOS.h"
#include "task.h"
void myhttp_get_task(void *pvParameters)
{
    printf_rtos("HTTP GET Task (Optimized) started.\n");

    // --- 声明所有需要用到的变量 ---
    struct addrinfo hints = {0};
    struct addrinfo *res = NULL;
    int client_socket = -1; // 初始化为-1，表示无效的socket
    int ret; // 用于接收函数返回值
    struct sockaddr_in *server_addr=NULL;

    // --- 1. DNS 解析 ---
    // 配置 getaddrinfo 的期望参数
    hints.ai_family = AF_INET;       // 只查找 IPv4 地址
    hints.ai_socktype = SOCK_STREAM; // 我们需要 TCP 套接字

    // 使用循环确保 DNS 解析成功
    while(getaddrinfo(HTTP_SERVER_NAME, HTTP_SERVER_PORT_STR, &hints, &res) != 0)
    {
        printf_rtos("getaddrinfo failed, retrying in 3s...\n");
        vTaskDelay(pdMS_TO_TICKS(3000));
    }
    printf_rtos("DNS for %s resolved.\n", HTTP_SERVER_NAME);
    server_addr=(struct sockaddr_in *)res->ai_addr;
    printf_rtos("serverinfo:%s:%d\n",inet_ntoa(server_addr->sin_addr),ntohs(server_addr->sin_port));
    // --- 2. 创建并连接 TCP Socket ---
    // 从 DNS 解析结果中创建 socket
    client_socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if (client_socket < 0)
    {
        printf_rtos("Failed to create socket, errno:%d\n", errno);
        goto cleanup; // 跳转到清理代码
    }
    printf_rtos("Socket created successfully.\n");

    // 尝试连接服务器
    printf_rtos("Connecting to server...\n");
    ret = connect(client_socket, res->ai_addr, res->ai_addrlen);
    if (ret < 0)
    {
        printf_rtos("Connect failed, errno:%d\n", errno);
        goto cleanup; // 跳转到清理代码
    }
    printf_rtos("Connected successfully.\n");


    // --- 3. 构造并发送 HTTP GET 请求报文 ---
    char request[256] = {0}; // 请求缓冲区大小可以适当调整

    // 使用 snprintf 构造请求，并主动要求服务器关闭连接
    snprintf(request, sizeof(request),
             "GET %s HTTP/1.0\r\n"
             "Host: %s\r\n"
             "Connection: close\r\n" // 【好习惯】主动要求服务器关闭连接，避免长连接僵局
             "User-Agent: stm32-lwip\r\n\r\n",
             HTTP_REQUEST_URI, HTTP_SERVER_NAME);

    printf_rtos("Sending HTTP request...\n---\n%s---\n", request);

    // 【优化点】使用循环确保所有数据都发送出去
    int bytes_to_send = strlen(request);
    int bytes_sent = 0;
    while (bytes_sent < bytes_to_send)
    {
        ret = send(client_socket, request + bytes_sent, bytes_to_send - bytes_sent, 0);
        if (ret < 0)
        {
            printf_rtos("Send failed, errno:%d\n", errno);
            goto cleanup; // 发送失败，跳转到清理代码
        }
        bytes_sent += ret; // 累加已发送的字节数
    }
    printf_rtos("HTTP request sent successfully.\n");


    // --- 4. 循环接收服务器响应 ---
    printf_rtos("Receiving HTTP response...\n---\n");
    char recv_buffer[256]; // 接收缓冲区
    int recv_len;

    do {
        // 接收数据g
        recv_len = recv(client_socket, recv_buffer, sizeof(recv_buffer) - 1, 0);
        if (recv_len > 0) {
            // 【优化点】手动添加字符串结束符，保证打印安全
            recv_buffer[recv_len] = '\0';
            printf_rtos("%s", recv_buffer); // 直接打印，不额外加换行
        }
    } while (recv_len > 0); // 只要还能收到数据(recv_len>0)，就一直循环

    // 当 recv_len 返回 0 (连接正常关闭) 或 -1 (出错) 时，循环结束
    printf_rtos("\n---\nFinished receiving data.\n");


// --- 5. 清理工作 ---
// 使用 goto 标签，可以确保无论函数从哪里退出，资源都能被正确释放
cleanup:
    if (res != NULL)
    {
        freeaddrinfo(res); // 释放 getaddrinfo 分配的内存
        printf_rtos("DNS result memory freed.\n");
    }
    if (client_socket >= 0)
    {
        closesocket(client_socket); // 关闭套接字
        printf_rtos("Socket closed.\n");
    }

    printf_rtos("HTTP GET Task finished.\n");
    vTaskDelete(NULL); // 【关键】任务结束时自我销毁
}